home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Diamond Collection / The Diamond Collection (Software Vault)(Digital Impact).ISO / cdr44 / wgtrun.zip / RUN4.C < prev    next >
C/C++ Source or Header  |  1995-02-21  |  8KB  |  391 lines

  1. #include <wgt5.h>
  2. #include <math.h>
  3.  
  4. /*
  5.  run4.c
  6.  
  7.  Same as run3.c, only with timer controlled animation.
  8.  Try running it on different speed computers, or turn your turbo off.
  9.  
  10.  
  11. */
  12.  
  13. #define TICKS(hz) ((int)(1193182L/(hz)))
  14.  
  15. unsigned char shadowtable[256];    /* Shadow table */
  16. unsigned char *transparency_table; /* a 65536 byte table,
  17.                       allocated dynamically */
  18.  
  19. color pal[256];         /* The palette used for every graphic image */
  20. block sprites[200];     /* Array of images for the running robot */
  21.  
  22. block background;       /* Holds the background scrolling image */
  23. block work;             /* Page for constructing each frame */
  24.  
  25. int animation_count;    /* Used for animation timing */
  26. int movement_multiplier;/* Number of times to move objects, ground, etc */
  27.  
  28. /* A structure which holds the scrolling values for each horizontal line */
  29. typedef struct
  30.  {
  31.   int x;                /* Current x value, shifted by 8 */
  32.   int increment;        /* fixed point increment */
  33.  } line_scroll;
  34. line_scroll lines[80];  /* 80 scrolling lines along the ground */
  35.  
  36. /* A simple sprite structure */
  37. typedef struct
  38.  {
  39.   int x;
  40.   int y;
  41.   int anm;              /* Sprite number */
  42.  } sprite;
  43. sprite people[5];
  44.  
  45.  
  46. int backx = 0;          /* X value for the scrolling rocks */
  47. int backinc;            /* X increment for scrolling rocks */
  48.  
  49.  
  50.  
  51.  
  52. /* Loads the graphics files, and allocates buffers */
  53. void load_graphics (void)
  54. {
  55.  work = wallocblock (320, 200);
  56.  /* Allocate a work buffer */
  57.  
  58.  wloadsprites (pal, "run.spr", sprites, 0, 199);
  59.  background = wloadgif ("street.gif", pal);
  60.  wsetpalette (0, 255, pal);
  61.  
  62.  transparency_table = (unsigned char *)malloc (65536);
  63. }
  64.  
  65.  
  66.  
  67. /* Frees the buffers and sprites */
  68. void free_graphics (void)
  69. {
  70.  free (transparency_table);
  71.  wfreesprites (sprites, 0, 199);
  72.  wfreeblock (background);
  73.  wfreeblock (work);
  74. }
  75.  
  76.  
  77. /* Set up the initial scrolling values */
  78. void init_lines (void)
  79. {
  80. int i;
  81. int inc;
  82.  
  83.  inc = 128;     /* slowest scrolling speed (128/256 of a pixel */
  84.  
  85.  backx = 0;     /* rocks x value */
  86.  backinc = inc; /* rocks same speed as the ground */
  87.  
  88.  for (i = 0; i < 80; i++)
  89.   {
  90.    lines[i].x = 0;              /* clear out the x value */
  91.    lines[i].increment = inc;    /* set the scroll speed */
  92.    inc += 32;                   /* Make the next row move faster */
  93.   }
  94.  
  95. }
  96.  
  97.  
  98.  
  99. /* Construct the background image */
  100. void animate_lines (void)
  101. {
  102. block source1, source2;
  103. block dest1, dest2;
  104. block origsource, origdest;
  105. int i;
  106. int x;
  107. int mult;
  108.  
  109.  wcopyscreen (0, 0, 319, 51, background, 0, 0, work);
  110.  /* Draw the moon stationary */
  111.  
  112.  /* Scroll the rocks */
  113.  for (mult = 0; mult <= movement_multiplier; mult++)
  114.    {
  115.     backx += backinc;
  116.     if (backx >= 81920)   /* 81920 is 320 << 8 */
  117.        backx -= 81920;
  118.    }
  119.  
  120.  x = backx >> 8;
  121.  
  122.  /* Copy the rocks */
  123.  wcopyscreen (x, 52, 319, 119, background, 0, 52, work);
  124.  if (x > 0)
  125.    wcopyscreen (0, 52, x-1, 119, background, 320 - x, 52, work);
  126.  
  127.  
  128.  origdest = abuf + 120 * 320;           /* First row to copy */
  129.  origsource = background + 120 * 320;   /* First row to copy */
  130.  
  131.  for (i = 0; i < 80; i++)
  132.   {
  133.    /* Scroll this line */
  134.    for (mult = 0; mult <= movement_multiplier; mult++)
  135.     {
  136.      lines[i].x += lines[i].increment;
  137.      if (lines[i].x >= 81920)   /* 81920 is 320 << 8, wraps scroll around */
  138.     lines[i].x -= 81920;
  139.     }
  140.    
  141.    x = lines[i].x >> 8;
  142.    /* Get the x coord */
  143.  
  144.    dest1 = origdest + i * 320;
  145.    dest2 = dest1 + (319 - x);
  146.    source1 = origsource + i * 320;
  147.    source2 = source1 + x;
  148.    
  149.    /* Copy the line in two steps */
  150.    memcpy (dest1, source2, 320 - x);
  151.    if (x > 0)
  152.     memcpy (dest2, source1, x + 1);
  153.    
  154.   }
  155.  
  156. }
  157.  
  158.  
  159.  
  160. /* Animates and displays the running man */
  161. void animate_man (void)
  162. {
  163. int mult;
  164.  
  165.  for (mult = 0; mult <= movement_multiplier; mult++)
  166.  {
  167.   people[0].anm++;
  168.   if (people[0].anm > 29)
  169.     people[0].anm = 0;
  170.  }
  171.  
  172.  wputblock_shade (people[0].x, 158, sprites[people[0].anm+30],
  173.         shadowtable, 1);
  174.  wputblock_shade (people[0].x, people[0].y, sprites[people[0].anm],
  175.         transparency_table, 2);
  176. }
  177.  
  178.  
  179.  
  180. void wcreate_shadow_table (color *palette)
  181. {
  182. float fr, fg, fb;
  183. long ir, ig, ib;
  184.  
  185. long absr, absg, absb;
  186.  
  187.  
  188. int r,g,b;
  189.  
  190. short col;
  191. short findcol;
  192.  
  193. unsigned long lowest;
  194. unsigned char bestfit;
  195. unsigned long coldif;
  196.  
  197.  for (col = 0; col < 256; col++)
  198.   {
  199.  
  200.    fr = (float)palette[col].r * (0.5);
  201.    fg = (float)palette[col].g * (0.5);
  202.    fb = (float)palette[col].b * (0.5);
  203.  
  204.    ir = fr;
  205.    ig = fg;
  206.    ib = fb;
  207.  
  208.    lowest = 655350;
  209.    for  (findcol = 0; findcol < 256; findcol++)
  210.     {
  211.       absr = abs ( (long)palette[findcol].r - ir);
  212.       absg = abs ( (long)palette[findcol].g - ig);
  213.       absb = abs ( (long)palette[findcol].b - ib);
  214.  
  215.       coldif = absr + absg + absb;
  216.       if  ((coldif < lowest) && (findcol != col))
  217.       {
  218.     lowest = coldif;
  219.     bestfit = findcol;
  220.       }
  221.     }
  222.    shadowtable[col] = bestfit;
  223.   }
  224.  
  225. }
  226.  
  227.  
  228. void wcreate_transparency_table (color *pal)
  229. {
  230. float lightlevel1;
  231. float lightlevel2;
  232. float fr, fg, fb;
  233. float fr2, fg2, fb2;
  234. long ir, ig, ib;
  235.  
  236. long absr, absg, absb;
  237.  
  238. short col, col2;
  239. short findcol;
  240.  
  241. unsigned long lowest;
  242. unsigned char bestfit;
  243. unsigned long coldif;
  244.  
  245.  
  246.  lightlevel1 = 0.5;     /* Percent of color 1 */
  247.  lightlevel2 = 0.5;     /* Percent of color 2 */
  248.  
  249.  /* Lightlevel1 and lightlevel2 must total to 1 */
  250.  
  251.  /* Transparency is created by taking two colors, multiplying the
  252.  RGB values by a percentage, and adding the RGB values together.  The
  253.  new color will contain a little bit of each oringal color. */
  254.  
  255.  
  256.  /* For each of the 256 colors, we can mix with any other color, therefore
  257.  we need a 256x256 table. */
  258.  
  259.  wtextcolor (15);
  260.  wtexttransparent (TEXTFGBG);
  261.  wgtprintf (0, 0, NULL, "Making transparency table...", col2);
  262.  
  263.  for (col2 = 0; col2 < 256; col2++)
  264.  {
  265.   for (col = 0; col < 256; col++)
  266.   {
  267.    fr = (float)pal[col].r * lightlevel1;
  268.    fg = (float)pal[col].g * lightlevel1;
  269.    fb = (float)pal[col].b * lightlevel1;
  270.  
  271.    fr2= (float)pal[col2].r * lightlevel2;
  272.    fg2= (float)pal[col2].g * lightlevel2;
  273.    fb2= (float)pal[col2].b * lightlevel2;
  274.  
  275.    ir = (fr + fr2);
  276.    ig = (fg + fg2);
  277.    ib = (fb + fb2);
  278.  
  279.    lowest = 655350;
  280.    for  (findcol = 0; findcol < 256; findcol++)
  281.     {
  282.       absr = abs ( (long)pal[findcol].r - ir) * 30;
  283.       absg = abs ( (long)pal[findcol].g - ig) * 59;
  284.       absb = abs ( (long)pal[findcol].b - ib) * 11;
  285.  
  286.       coldif = sqrt(absr*absr + absg*absg + absb*absb);
  287.       if  (coldif < lowest)
  288.       {
  289.     lowest = coldif;
  290.     bestfit = findcol;
  291.       }
  292.     }
  293.    transparency_table[col2 * 256L + col] = bestfit;
  294.   }
  295.  
  296.   wgtprintf (0, 8, NULL, "Color %03hi", col2);
  297.  }
  298.  
  299. }
  300.  
  301.  
  302. void animation_timer (void)
  303. {
  304.  animation_count++;
  305. }
  306.  
  307.  
  308.  
  309. int load_table (char *filename, block table, int size)
  310. {
  311. FILE *in;
  312.  
  313.  in = fopen (filename, "rb");
  314.  if (in == NULL)
  315.    return 0;
  316.  fread (table, size, 1, in);
  317.  fclose (in);
  318.  return 1;
  319. }
  320.  
  321.  
  322. void save_table (char *filename, block table, int size)
  323. {
  324. FILE *out;
  325.  
  326.  out = fopen (filename, "wb");
  327.  fwrite (table, size, 1, out);
  328.  fclose (out);
  329.  
  330. }
  331.  
  332.  
  333.  
  334. void main (void)
  335. {
  336.  
  337.  vga256 ();
  338.  
  339.  load_graphics ();
  340.  
  341.  init_lines ();
  342.  
  343.  /* Set the position of the running man */
  344.  people[0].x = 120;
  345.  people[0].y = 50;
  346.  people[0].anm = 0;
  347.  
  348.  wcreate_shadow_table (pal);
  349.  
  350.  if (!load_table ("trans.dat", transparency_table, 65536))
  351.   { 
  352.    wcreate_transparency_table (pal);
  353.    save_table ("trans.dat", transparency_table, 65536); 
  354.   }
  355.  
  356.  
  357.  animation_count = 0;
  358.  winittimer ();
  359.  wstarttimer (animation_timer, TICKS (60));
  360.  
  361.  do {
  362.   wsetscreen (work);
  363.  
  364.   movement_multiplier = animation_count;
  365.   if (movement_multiplier > 1)
  366.    {
  367.     /* Since our running animation is 30 frames, I'll make this animation
  368.     update every other frame (half of 60).
  369.     
  370.     /* If animation_count is odd, keep the odd count */
  371.     animation_count = movement_multiplier % 2;
  372.     
  373.     movement_multiplier /= 2;
  374.     /* Halve the animation speed */
  375.  
  376.     animate_lines ();
  377.     animate_man ();
  378.     wnormscreen ();
  379.  
  380.     wputblock (0, 0, work, 0);
  381.    }
  382.   } while (!kbhit ());
  383.  
  384.  wstoptimer ();
  385.  wdonetimer ();
  386.  
  387.  free_graphics ();
  388.  wsetmode (3);
  389. }
  390.  
  391.